package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import com.ruoyi.system.dao.BlsDao;
import com.ruoyi.system.domain.dto.BlsDto;
import com.ruoyi.system.domain.vo.BlsVo;
import com.ruoyi.system.service.BlsService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ruoyi.common.constant.UserConstants.QuestionCode.*;

@Service
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public class BlsServiceImpl implements BlsService {

    @Resource
    private BlsDao blsDao;
    @Value("${dangan.zyTemplate}")
    private String templatePath;

    @Override
    public List<BlsVo.BlsZlInfoVo> queryZl(BlsDto.Query dto) throws ParseException {
        List<BlsVo.BlsZlInfoVo> blsZlInfoVos = blsDao.selectInfo(dto);
        if (CollectionUtil.isNotEmpty(blsZlInfoVos)) {
            for (BlsVo.BlsZlInfoVo blsZlInfoVo : blsZlInfoVos) {
                getIndex(blsZlInfoVo);
            }
        }
        return blsZlInfoVos;
    }

    private BlsVo.BlsZlInfoVo getIndex(BlsVo.BlsZlInfoVo result) throws ParseException {
        List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> recordVoList = result.getRecordVoList();
        if (CollectionUtil.isNotEmpty(recordVoList)) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Map<String, List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo>> map = recordVoList.stream().collect(Collectors.groupingBy(BlsVo.BlsJzInfoVo.PmsArchivesRecordVo::getCode));
            //发病时间
            List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> fbsjRecordVo = map.get(JBXX_FBSJ.getKey());
            Date fbsj = new Date();
            if (fbsjRecordVo != null && StrUtil.isNotEmpty(fbsjRecordVo.get(0).getAnswer())) {
                fbsj = sdf.parse(fbsjRecordVo.get(0).getAnswer());
            }
            //到院时间
            List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> dysjRecordVo = map.get(JBXX_DY_TIME.getKey());
            Date dysj = new Date();
            if (dysjRecordVo != null && StrUtil.isNotEmpty(dysjRecordVo.get(0).getAnswer())) {
                dysj = sdf.parse(dysjRecordVo.get(0).getAnswer());
            }
            //ct时间
            List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> ctsjRecordVo = map.get(RYPG_CT_JCKS_TIME.getKey());
            Date ctsj = new Date();
            if (ctsjRecordVo != null) {
                if (StrUtil.isNotEmpty(ctsjRecordVo.get(0).getAnswer())) {
                    ctsj = sdf.parse(ctsjRecordVo.get(0).getAnswer());
                }
            }
            //溶栓时间
            List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> rssjRecordVo = map.get(JMRS_TIME.getKey());
            Date rssj = new Date();
            if (rssjRecordVo != null && StrUtil.isNotEmpty(rssjRecordVo.get(0).getAnswer())) {
                rssj = sdf.parse(rssjRecordVo.get(0).getAnswer());
            }
            //穿刺完成时间
            List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> ccwcsjRecordVo = map.get(ZL_JRZT_CCWCSJ.getKey());
            Date zqsj = new Date();
            if (ccwcsjRecordVo != null && StrUtil.isNotEmpty(ccwcsjRecordVo.get(0).getAnswer())) {
                zqsj = sdf.parse(ccwcsjRecordVo.get(0).getAnswer());
            }
            //血管再通时间
            List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> xgztsjRecordVo = map.get(XGZL_SCZT_TIME.getKey());
            Date xgztsj = new Date();
            if (xgztsjRecordVo != null && StrUtil.isNotEmpty(xgztsjRecordVo.get(0).getAnswer())) {
                xgztsj = sdf.parse(xgztsjRecordVo.get(0).getAnswer());
            }
            //计算质控指标值
            //DNT 到达医院(到达急诊时间)-溶栓开始的时间(团注开始时间)
            if (dysj != null && rssj != null) {
                Integer dnt = (int) ((rssj.getTime() - dysj.getTime()) / 1000);
                result.setDnt(dnt);
            }
            //ODT 发病(发病时间/最后正常时间) 达到医院的时间(到达医院时间，通常是到达急诊时间)
            if (fbsj != null && dysj != null) {
                Integer odt = (int) ((dysj.getTime() - fbsj.getTime()) / 1000);
                result.setOdt(odt);
            }
            //DIT 到达医院(到达急诊时间)影像时间(CT/核磁完成时间)
            if (dysj != null && ctsj != null) {
                Integer dit = (int) ((ctsj.getTime() - dysj.getTime()) / 1000);
                result.setDit(dit);
            }
            //ONT 发病-溶栓开始的时间
            if (fbsj != null && rssj != null) {
                Integer ont = (int) ((rssj.getTime() - fbsj.getTime()) / 1000);
                result.setOnt(ont);
            }
            //DPT 到达医院-置鞘时间(取栓)
            if (dysj != null && zqsj != null) {
                Integer dpt = (int) ((zqsj.getTime() - dysj.getTime()) / 1000);
                result.setDpt(dpt);
            }
            //OPT 发病-置鞘时间(取栓)
            if (fbsj != null && zqsj != null) {
                Integer opt = (int) ((zqsj.getTime() - fbsj.getTime()) / 1000);
                result.setOpt(opt);
            }
            //PRT 置鞘-血管再通时间
            if (zqsj != null && xgztsj != null) {
                Integer prt = (int) ((xgztsj.getTime() - zqsj.getTime()) / 1000);
                result.setPrt(prt);
            }
        }
        return result;
    }
    @Override
    public void exportZl(HttpServletResponse response, BlsDto.Query dto) throws ParseException {
        BigExcelWriter excelWriter = ExcelUtil.getBigWriter(templatePath);
//        excelWriter.writeHeadRow(headerList);
        List<BlsVo.BlsZlInfoVo> blsZlInfoVos = queryZl(dto);
        if (CollectionUtil.isEmpty(blsZlInfoVos)) {
            excelWriter.close();
            return;
        }

        int row = 1;
        for (int i = 0; i < blsZlInfoVos.size(); i++) {
            row += 1;
            excelWriter.writeCellValue(0, row, blsZlInfoVos.get(i).getName());
            if (blsZlInfoVos.get(i).getSex() != null) {
                excelWriter.writeCellValue(1, row, blsZlInfoVos.get(i).getSex() == 0 ? "女" : "男");//"性别"
            }
            if (IdcardUtil.isValidCard(blsZlInfoVos.get(i).getIdCard())) {
                excelWriter.writeCellValue(2, row, IdcardUtil.getAgeByIdCard(blsZlInfoVos.get(i).getIdCard()));
            }
            excelWriter.writeCellValue(3, row, blsZlInfoVos.get(i).getNation());

            if (StrUtil.isNotEmpty(blsZlInfoVos.get(i).getIdCard())) {
                excelWriter.writeCellValue(4, row, IdcardUtil.getBirth(blsZlInfoVos.get(i).getIdCard()));
                excelWriter.writeCellValue(5, row, blsZlInfoVos.get(i).getIdCard());
            }

            List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo> recordVoList = blsZlInfoVos.get(i).getRecordVoList();
            if (CollectionUtil.isEmpty(recordVoList)) {
                continue;
            }
            Map<String, List<BlsVo.BlsJzInfoVo.PmsArchivesRecordVo>> map = recordVoList.stream().collect(Collectors.groupingBy(BlsVo.BlsJzInfoVo.PmsArchivesRecordVo::getCode));

            //患者姓名
            //性别
            //年龄
            //民族
            //出生日期
            //身份证号
            //联系人姓名
            //联系人电话
            //
            //住院号
            //入院途径

            //
            //出院日期
            //住院天数

            //离院方式
            //住院总费用
            //主要诊断
            //主要诊断名称
            //主要诊断编码
            excelWriter.writeCellValue(6, row, blsZlInfoVos.get(i).getName());
            excelWriter.writeCellValue(7, row, blsZlInfoVos.get(i).getPhone());
            excelWriter.writeCellValue(8, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_YLFF.getKey())) ? map.get(ZL_JBXX_YLFF.getKey()).get(0).getAnswer() : "");//主要医疗付费方式
            excelWriter.writeCellValue(9, row, blsZlInfoVos.get(i).getZyh());
            excelWriter.writeCellValue(10, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_RYTJ.getKey())) ? map.get(ZL_JBXX_RYTJ.getKey()).get(0).getAnswer() : "");

            if (blsZlInfoVos.get(i).getRysj() != null) {
                excelWriter.writeCellValue(11, row, DateUtil.date(blsZlInfoVos.get(i).getRysj()));//住院日期
            }
            if (blsZlInfoVos.get(i).getCysj() != null) {
                excelWriter.writeCellValue(12, row, DateUtil.date(blsZlInfoVos.get(i).getCysj()));
            }

            excelWriter.writeCellValue(13, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_ZYTS.getKey())) ? map.get(ZL_JBXX_ZYTS.getKey()).get(0).getAnswer() : "");
            excelWriter.writeCellValue(14, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_LYFS.getKey())) ? map.get(ZL_JBXX_LYFS.getKey()).get(0).getAnswer() : "");
            excelWriter.writeCellValue(15, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_ZYZFY.getKey())) ? map.get(ZL_JBXX_ZYZFY.getKey()).get(0).getAnswer() : "");

            excelWriter.writeCellValue(16, row, blsZlInfoVos.get(i).getZyzdmc());
//            excelWriter.writeCellValue(17, row, blsZlInfoVos.get(i).getZyzdbm());

//            excelWriter.writeCellValue(17, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_ZYTS.getKey())) ? map.get(ZL_JBXX_ZYTS.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(18, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_LYFS.getKey())) ? map.get(ZL_JBXX_LYFS.getKey()).get(0).getAnswer() : "");
            excelWriter.writeCellValue(17, row, blsZlInfoVos.get(i).getZdmc());
            excelWriter.writeCellValue(18, row, blsZlInfoVos.get(i).getZdbm());
//            excelWriter.writeCellValue(22, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_DIE_T.getKey())) ? map.get(ZL_JBXX_DIE_T.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(23, row, CollectionUtil.isNotEmpty(map.get(ZL_JBXX_DIE_R.getKey())) ? map.get(ZL_JBXX_DIE_R.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(24, row, CollectionUtil.isNotEmpty(map.get(ZL_FBQK_FBSJ.getKey())) ? map.get(ZL_FBQK_FBSJ.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(25, row, CollectionUtil.isNotEmpty(map.get(ZL_FBQK_DY_TIME.getKey())) ? map.get(ZL_FBQK_DY_TIME.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(26, row, CollectionUtil.isNotEmpty(map.get(ZL_RYPG_SBP.getKey())) ? map.get(ZL_RYPG_SBP.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(27, row, CollectionUtil.isNotEmpty(map.get(ZL_RYPG_DBP.getKey())) ? map.get(ZL_RYPG_DBP.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(28, row, CollectionUtil.isNotEmpty(map.get(ZL_CYPG_CYYY.getKey())) ? map.get(ZL_CYPG_CYYY.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(29, row, CollectionUtil.isNotEmpty(map.get(ZL_NCX_MZ.getKey())) ? map.get(ZL_NCX_MZ.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(30, row, CollectionUtil.isNotEmpty(map.get(ZL_NCX_SS.getKey())) ? map.get(ZL_NCX_SS.getKey()).get(0).getAnswer() : "");
//            excelWriter.writeCellValue(31, row, CollectionUtil.isNotEmpty(map.get(ZL_NCX_T_SS.getKey())) ? map.get(ZL_NCX_T_SS.getKey()).get(0).getAnswer() : "");

            excelWriter.writeCellValue(49, row, blsZlInfoVos.get(i).getSsmc());
            excelWriter.writeCellValue(50, row, blsZlInfoVos.get(i).getSsbm());
            excelWriter.writeCellValue(51, row, blsZlInfoVos.get(i).getSsrq());
        }

        String filename = StrUtil.format("zydn-{}.xlsx", DateUtil.date().toString("yyyyMMdd"));

        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=" + filename);
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            excelWriter.flush(out);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭writer，释放内存
            excelWriter.close();
            //此处记得关闭输出Servlet流
            IoUtil.close(out);
        }
    }

    @Override
    public List<BlsVo.BlsJzInfoVo> queryJz(BlsDto.Query dto) {
        return null;
    }
}
